From: Yehuda Katz Date: Tue, 29 Apr 2014 22:24:01 +0000 (-0700) Subject: Clean up config and support array inheritance X-Git-Tag: archive/raspbian/0.35.0-2+rpi1~3^2^2^2^2^2^2^2~1107 X-Git-Url: https://dgit.raspbian.org/%22http://www.example.com/cgi/success//%22http:/www.example.com/cgi/success/?a=commitdiff_plain;h=b15cb1de5d2646c48614199d7005b862844f48b6;p=cargo.git Clean up config and support array inheritance --- diff --git a/src/cargo/util/config.rs b/src/cargo/util/config.rs index f97385e2b..cf72a49c5 100644 --- a/src/cargo/util/config.rs +++ b/src/cargo/util/config.rs @@ -1,7 +1,9 @@ extern crate collections; +extern crate serialize; extern crate toml; use super::super::{CargoResult,ToCargoError,CargoError}; +use serialize::{Encodable,Encoder}; use std::{io,fmt}; #[deriving(Eq,TotalEq,Clone,Encodable,Decodable)] @@ -10,16 +12,50 @@ pub enum Location { Global } -#[deriving(Eq,TotalEq,Clone,Encodable,Decodable,Show)] +#[deriving(Eq,TotalEq,Clone,Decodable)] enum ConfigValueValue { String(~str), - List(~[~str]) + List(Vec<~str>) } -#[deriving(Eq,TotalEq,Clone,Encodable,Decodable)] +impl fmt::Show for ConfigValueValue { + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + match self { + &String(ref string) => write!(f.buf, "{}", string), + &List(ref list) => write!(f.buf, "{}", list) + } + } +} + +impl> Encodable for ConfigValueValue { + fn encode(&self, s: &mut S) -> Result<(), E> { + match self { + &String(ref string) => { + try!(string.encode(s)); + }, + &List(ref list) => { + try!(list.encode(s)); + } + } + + Ok(()) + } +} + +#[deriving(Eq,TotalEq,Clone,Decodable)] pub struct ConfigValue { value: ConfigValueValue, - path: ~str + path: Vec<~str> +} + +impl> Encodable for ConfigValue { + fn encode(&self, s: &mut S) -> Result<(), E> { + s.emit_map(2, |s| { + try!(s.emit_map_elt_key(0, |s| "value".encode(s))); + try!(s.emit_map_elt_val(0, |s| self.value.encode(s))); + Ok(()) + }) + } } impl fmt::Show for ConfigValue { @@ -35,13 +71,9 @@ pub fn get_config(pwd: Path, key: &str) -> CargoResult { pub fn all_configs(pwd: Path) -> CargoResult> { let mut map = collections::HashMap::new(); - walk_tree(&pwd, |file| { - let _ = extract_all_configs(file).map(|configs| { - for (key, value) in configs.move_iter() { - map.find_or_insert(key, value); - } - }); - }); + try!(walk_tree(&pwd, |file| { + extract_all_configs(file, &mut map) + })); Ok(map) } @@ -51,16 +83,15 @@ pub fn set_config(key: ~str, value: ~str, location: Location) -> CargoResult<()> Ok(()) } -fn find_in_tree(pwd: &Path, walk: |io::fs::File| -> CargoResult) -> Option { +fn find_in_tree(pwd: &Path, walk: |io::fs::File| -> CargoResult) -> CargoResult { let mut current = pwd.clone(); loop { let possible = current.join(".cargo").join("config"); if possible.exists() { - let res = io::fs::File::open(&possible).map(|file| walk(file)); - - match res { - Ok(Ok(res)) => return Some(res), + let file = try!(io::fs::File::open(&possible).to_cargo_error(~"", 1)); + match walk(file) { + Ok(res) => return Ok(res), _ => () } } @@ -68,20 +99,28 @@ fn find_in_tree(pwd: &Path, walk: |io::fs::File| -> CargoResult) -> Option if !current.pop() { break; } } - None + Err(CargoError::new(~"", 1)) } -fn walk_tree(pwd: &Path, walk: |io::fs::File| -> ()) { +fn walk_tree(pwd: &Path, walk: |io::fs::File| -> CargoResult<()>) -> CargoResult<()> { let mut current = pwd.clone(); + let mut err = false; loop { let possible = current.join(".cargo").join("config"); if possible.exists() { - let _ = io::fs::File::open(&possible).map(|file| walk(file)); + let file = try!(io::fs::File::open(&possible).to_cargo_error(~"", 1)); + match walk(file) { + Err(_) => err = false, + _ => () + } } + if err { return Err(CargoError::new(~"", 1)); } if !current.pop() { break; } } + + Ok(()) } fn extract_config(file: io::fs::File, key: &str) -> CargoResult { @@ -96,12 +135,10 @@ fn extract_config(file: io::fs::File, key: &str) -> CargoResult { _ => return Err(CargoError::new(~"", 1)) }; - Ok(ConfigValue{ value: v, path: path }) + Ok(ConfigValue{ value: v, path: vec!(path) }) } -fn extract_all_configs(file: io::fs::File) -> CargoResult> { - let mut map = collections::HashMap::new(); - +fn extract_all_configs(file: io::fs::File, map: &mut collections::HashMap<~str, ConfigValue>) -> CargoResult<()> { let path = try!(file.path().as_str().to_cargo_error(~"", 1)).to_owned(); let mut buf = io::BufferedReader::new(file); let root = try!(toml::parse_from_buffer(&mut buf).to_cargo_error(~"", 1)); @@ -109,11 +146,41 @@ fn extract_all_configs(file: io::fs::File) -> CargoResult { map.insert(key.to_owned(), ConfigValue { value: String(val.to_owned()), path: path.clone() }); } - &toml::Array(ref val) => { map.insert(key.to_owned(), ConfigValue { value: List(val.iter().map(|s: &toml::Value| s.to_str()).collect()), path: path.clone() }); } + &toml::String(ref val) => { map.insert(key.to_owned(), ConfigValue { value: String(val.to_owned()), path: vec!(path.clone()) }); } + &toml::Array(ref val) => { + let config = map.find_or_insert_with(key.to_owned(), |_| { + ConfigValue { path: vec!(), value: List(vec!()) } + }); + + try!(merge_array(config, val.as_slice(), path.as_slice())); + }, _ => () } } - Ok(map) + Ok(()) +} + +fn merge_array(existing: &mut ConfigValue, val: &[toml::Value], path: &str) -> CargoResult<()> { + match existing.value { + String(_) => return Err(CargoError::new(~"", 1)), + List(ref mut list) => { + let new_list: Vec> = val.iter().map(|s: &toml::Value| toml_string(s)).collect(); + if new_list.iter().any(|v| v.is_err()) { + return Err(CargoError::new(~"", 1)); + } else { + let new_list: Vec<~str> = new_list.move_iter().map(|v| v.unwrap()).collect(); + list.push_all(new_list.as_slice()); + existing.path.push(path.to_owned()); + Ok(()) + } + } + } +} + +fn toml_string(val: &toml::Value) -> CargoResult<~str> { + match val { + &toml::String(ref str) => Ok(str.to_owned()), + _ => Err(CargoError::new(~"", 1)) + } } diff --git a/vimrc b/vimrc deleted file mode 100644 index db5d5142f..000000000 --- a/vimrc +++ /dev/null @@ -1 +0,0 @@ -au BufRead,BufNewFile *.rs set filetype=rust smartindent tabstop=4 shiftwidth=4 expandtab